home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / pascal / tptc17sc.zip / TPCSTMT.INC < prev    next >
Text File  |  1988-03-25  |  24KB  |  1,136 lines

  1.  
  2. (*
  3.  * TPTC - Turbo Pascal to C translator
  4.  *
  5.  * (C) 1988 Samuel H. Smith (rev. 13-Feb-88)
  6.  *
  7.  *)
  8.  
  9. (********************************************************************)
  10. (*
  11.  * control statement processors
  12.  *    for, while, repeat, with, idents
  13.  *
  14.  * all expect tok to be keyword
  15.  * all exit at end of statement with ltok as ; or end
  16.  *
  17.  *)
  18.  
  19. procedure pfor;
  20. var
  21.    up:       boolean;
  22.    id:       string80;
  23.    low,high: string80;
  24.  
  25. begin
  26.    if debug_parse then write(' <for>');
  27.  
  28.    nospace := true;
  29.    puts('for (');
  30.    gettok;   {consume the FOR}
  31.  
  32.    id := plvalue;
  33.    gettok;   {consume the :=}
  34.  
  35.    low := pexpr;
  36.  
  37.    if tok = 'TO' then
  38.       up := true
  39.    else
  40.  
  41.    if tok = 'DOWNTO' then
  42.       up := false;
  43.  
  44.    gettok;
  45.    high := pexpr;
  46.  
  47.    if up then
  48.       puts(id+' = '+low+'; '+id+' <= '+high+'; '+id+'++) ')
  49.    else
  50.       puts(id+' = '+low+'; '+id+' >= '+high+'; '+id+'--) ');
  51.  
  52.    nospace := false;
  53.    gettok;   {consume the DO}
  54.    pstatement;
  55. end;
  56.  
  57.  
  58. (********************************************************************)
  59. procedure pwhile;
  60. begin
  61.    if debug_parse then write(' <while>');
  62.    gettok;   {consume the WHILE}
  63.  
  64.    nospace := true;
  65.    puts('while ('+pexpr+') ');
  66.    nospace := false;
  67.  
  68.    gettok;   {consume the DO}
  69.    pstatement;
  70. end;
  71.  
  72.  
  73. (********************************************************************)
  74. procedure pwith;
  75. var
  76.    prefix: string;
  77.    levels: integer;
  78.    
  79. begin
  80.    if debug_parse then write(' <with>');
  81.    gettok;   {consume the WITH}
  82.  
  83.    {warning('WITH not translated');}
  84.    levels := 0;
  85.    puts('{ ');
  86.    nospace := true;
  87.       
  88.    repeat
  89.       if tok[1] = ',' then 
  90.       begin
  91.          gettok;
  92.          newline;
  93.          puts('  ');
  94.       end;
  95.          
  96.       prefix := plvalue;
  97.       make_pointer(prefix);
  98.       
  99.       inc(levels);
  100.       inc(withlevel);
  101.       puts('void *with'+itoa(withlevel)+' = '+prefix+'; ');
  102.       
  103.    until tok[1] <> ',';
  104.    
  105.    nospace := false;
  106.    gettok;   {consume the DO}
  107.    
  108.    if tok[1] <> '{' then
  109.       pstatement
  110.    else
  111.  
  112.    begin
  113.       gettok;                 {consume the open brace}
  114.    
  115.       while (tok[1] <> '}') and not recovery do
  116.       begin
  117.          pstatement;          {process the statement}
  118.    
  119.          if tok[1] = ';' then
  120.          begin
  121.             puttok;
  122.             gettok;           {get first token of next statement}
  123.          end;
  124.       end;
  125.       
  126.       gettok;                 {consume the close brace}
  127.    end;
  128.  
  129.    puts('   } ');
  130.    newline;
  131.  
  132.    if tok[1] = ';' then
  133.       gettok;
  134.  
  135.    dec(withlevel,levels);
  136. end;
  137.  
  138.  
  139. (********************************************************************)
  140. procedure prepeat;
  141. begin
  142.    if debug_parse then write(' <repeat>');
  143.    puts('do { ');
  144.    gettok;
  145.  
  146.    while (tok <> 'UNTIL') and not recovery do
  147.    begin
  148.       pstatement;
  149.  
  150.       if tok[1] = ';' then
  151.       begin
  152.          puttok;
  153.          gettok;
  154.       end;
  155.    end;
  156.  
  157.    gettok;
  158.    nospace := true;
  159.    puts('}  while (!('+ pexpr+ '))');
  160.    nospace := false;
  161. end;
  162.  
  163.  
  164. (********************************************************************)
  165. procedure pcase;
  166. var
  167.    ex:  string80;
  168.    ex2: string80;   
  169.    i:   integer;
  170.    c:   char;
  171.  
  172. begin
  173.    if debug_parse then write(' <case>');
  174.    gettok;
  175.    ex := pexpr;
  176.    puts('switch ('+ex+') {');
  177.  
  178.    gettok;   {consume the OF}
  179.  
  180.    while (tok[1] <> '}') and (tok <> 'ELSE') and not recovery do
  181.    begin
  182.  
  183.       repeat
  184.          if tok[1] = ',' then
  185.             gettok;
  186.  
  187.          if tok = '..' then
  188.          begin
  189.             gettok;
  190.             ex2 := pexpr;
  191.             
  192.             if (ex2[1] = '''') or (ex2[1] = '"') then
  193.                for c := succ(ex[2]) to ex2[2] do
  194.                begin
  195.                   newline;
  196.                   puts('case '''+c+''':   ');
  197.                end
  198.             else
  199.             
  200.             if atoi(ex2) - atoi(ex) > 128 then
  201.             begin
  202.                ltok := ex+'..'+ex2;
  203.                warning('Gigantic case range');
  204.             end 
  205.             else
  206.             
  207.             for i := succ(atoi(ex)) to atoi(ex2) do
  208.             begin
  209.                newline;
  210.                write(ofd[unitlevel],'case ',i,':   ');
  211.             end;
  212.          end
  213.          else
  214.          
  215.          begin
  216.             ex := pexpr;
  217.             newline;
  218.             puts('case '+ex+':   ');
  219.          end;
  220.  
  221.       until (tok[1] = ':') or recovery;
  222.       gettok;
  223.  
  224.       if (tok[1] <> '}') and (tok <> 'ELSE') then
  225.          pstatement;
  226.       puts('break; ');
  227.       newline;
  228.  
  229.       if tok[1] = ';' then
  230.          gettok;
  231.    end;
  232.  
  233.    if tok = 'ELSE' then
  234.    begin
  235.       newline;
  236.       puts('default: ');
  237.       gettok;   {consume the else}
  238.  
  239.       while (tok[1] <> '}') and not recovery do
  240.       begin
  241.          if (tok[1] <> '}') and (tok <> 'ELSE') then
  242.             pstatement;
  243.          if tok[1] = ';' then
  244.             gettok;
  245.       end;
  246.    end;
  247.  
  248.    puttok;
  249.    gettok;
  250.  
  251.    if tok[1] = ';' then
  252.       gettok;
  253. end;
  254.  
  255.  
  256. (********************************************************************)
  257. procedure pif;
  258. var
  259.    pspace: integer;
  260. begin
  261.    if debug_parse then write(' <if>');
  262.    gettok;   {consume the IF}
  263.  
  264.    pspace := length(spaces);
  265.    nospace := true;
  266.    puts('if ('+ pexpr+ ') ');
  267.    nospace := false;
  268.    
  269.    gettok;   {consume the THEN}
  270.  
  271.    if (tok[1] <> '}') and (tok <> 'ELSE') then
  272.       pstatement;
  273.  
  274.    if tok = 'ELSE' then
  275.    begin
  276.       spaces := copy(spaces,1,pspace);
  277.       if not linestart then
  278.          newline;
  279.       puts('else ');
  280.  
  281.       gettok;
  282.       if tok[1] <> '}' then
  283.          pstatement;
  284.    end;
  285.  
  286. end;
  287.  
  288.  
  289. (********************************************************************)
  290. procedure pexit;
  291. begin
  292.    if debug_parse then write(' <exit>');
  293.    puts('return;');
  294.  
  295.    gettok;
  296.    if tok[1] = ';' then
  297.       gettok;
  298. end;
  299.  
  300.  
  301. (********************************************************************)
  302. procedure pgoto;
  303. var
  304.    ex:  anystring;
  305.  
  306. begin
  307.    gettok;                      {consume the goto}
  308.  
  309.    if toktype = number then
  310.       ltok := 'label_' + ltok;  {modify numeric labels}
  311.  
  312.    puts('goto '+ltok+';');
  313.  
  314.    gettok;                      {consume the label}
  315.  
  316.    if tok[1] = ';' then
  317.       gettok;
  318. end;
  319.  
  320.  
  321. (********************************************************************)
  322. procedure phalt;
  323. var
  324.    ex: anystring;
  325.  
  326. begin
  327.    if debug_parse then write(' <halt>');
  328.    gettok;
  329.  
  330.    if tok[1] = '(' then
  331.    begin
  332.       gettok;
  333.       ex := pexpr;
  334.       gettok;
  335.    end
  336.    else
  337.       ex := '0';     {default exit expression}
  338.  
  339.    puts('exit('+ex+');');
  340.  
  341.    if tok[1] = ';' then
  342.       gettok;
  343. end;
  344.  
  345.  
  346. (********************************************************************)
  347. procedure pread;
  348. var
  349.    ctl:  string;
  350.    func: anystring;
  351.    ex:   paramlist;
  352.    p:    string;
  353.    ln:   boolean;
  354.    ty:   string[2];
  355.    i:    integer;
  356.  
  357. begin
  358.    if debug_parse then write(' <read>');
  359.    
  360.    nospace := true;   {don't copy source whitespace to output during
  361.                        this processing.  this prevents spaces from
  362.                        getting moved around}
  363.  
  364.    ln := tok = 'READLN';
  365.    nospace := true;
  366.    func := 'scanv(';
  367.  
  368.    gettok;   {consume the read}
  369.  
  370.    if tok[1] = '(' then
  371.    begin
  372.       gettok;
  373.  
  374.       if ltok[1] = '[' then   {check for MT+ [addr(name)], form}
  375.       begin
  376.          gettok;   {consume the '[' }
  377.  
  378.          if tok[1] = ']' then
  379.             func := 'scanf('
  380.          else
  381.  
  382.          begin
  383.             gettok;   {consume the ADDR}
  384.             gettok;   {consume the '(' }
  385.             func := 'fiscanf(' + usetok + ',';
  386.             gettok;   {consume the ')'}
  387.          end;
  388.  
  389.          gettok;   {consume the ']'}
  390.          if tok[1] = ',' then
  391.             gettok;
  392.       end;
  393.  
  394.       ctl := '';
  395.       ex.n := 0;
  396.  
  397.       while (tok[1] <> ')') and not recovery do
  398.       begin
  399.          p := pexpr;
  400.          ty := exprtype;
  401.  
  402.          {convert to fprintf if first param is a file variable}
  403.          if (ex.n = 0) and (ty = '@') then
  404.             func := 'fs